package cn.thens.kdroid.core.storage

internal class CachedStorage<K, V>(private val storage: Storage<K, V>, private val cache: Storage<K, V>) : Storage<K, V> {
    override fun node(key: K): Storage.Node<V> {
        return Node(storage.node(key), cache.node(key))
    }

    override fun clear() {
        cache.clear()
        storage.clear()
    }

    override fun getAll(): Map<K, V> {
        return storage.getAll()
    }

    override fun getKeys(): Set<K> {
        return storage.getKeys()
    }

    class Node<V>(private val node: Storage.Node<V>, private val cache: Storage.Node<V>) : Storage.Node<V> {
        override fun get(): V {
            var value = cache.optional()
            if (value != null) return value
            value = node.get()
            cache.put(value)
            return value
        }

        override fun put(value: V) {
            cache.put(value)
            node.put(value)
        }

        override fun clear() {
            cache.clear()
            node.clear()
        }

        override fun exists(): Boolean {
            return node.exists()
        }
    }
}
